package org.exez.modules.visitor.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.exez.modules.visitor.constant.Enum;
import org.exez.modules.visitor.entity.PolicePay;
import org.exez.modules.visitor.mapper.PolicePayMapper;
import org.exez.modules.visitor.service.IPolicePayService;
import org.exez.modules.visitor.util.MD5;
import org.exez.modules.visitor.util.MinaClientHandle;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.List;

/**
 * @Description: 公安pay
 * @Author: exez-boot
 * @Date:   2020-08-19
 * @Version: V1.0
 */
@Service
public class PolicePayServiceImpl extends ServiceImpl<PolicePayMapper, PolicePay> implements IPolicePayService {

    @Override
    public void policePay(PolicePay policePay) {
        ConnectFuture connect = getConnect(policePay.getIp(), Integer.parseInt(policePay.getPort()), policePay.getPayId(), policePay.getSecret());
        if(connect.getSession() != null){
            getConnectToSend(connect, policePay.getPayId(), policePay.getSecret());
        }

    }

    @Override
    public PolicePay selectPolicePayByIpAndPort(String ip, String port) {
        LambdaQueryWrapper<PolicePay> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PolicePay::getIp, ip);
        queryWrapper.eq(PolicePay::getPort, port);
        return baseMapper.selectOne(queryWrapper);
    }
    @Override
    public ConnectFuture getConnect(String ip,int port,String payId,String secret){
        // TODO Auto-generated method stub
        IoConnector connector = new NioSocketConnector();
        connector.setConnectTimeoutMillis(30000);
        TextLineCodecFactory lineCodec=new TextLineCodecFactory(Charset.forName("UTF-8"));
        lineCodec.setDecoderMaxLineLength(1024*1024*1024); //1G
        lineCodec.setEncoderMaxLineLength(1024*1024*1024); //1G
        connector.getFilterChain().addLast("codec",
                new ProtocolCodecFilter(lineCodec));
        //String payId="1001";
        //String secret="002f0c86af67473aa280c8d5ef165a19";
        JSONObject json=new JSONObject();
        json.put("method", "connectCheck");
        JSONObject data=new JSONObject();
        long time=System.currentTimeMillis();
        data.put("payId", payId);
        data.put("time", time);
        try {
            data.put("sign", MD5.md5(secret+time));
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        json.put("data", data);
        connector.setHandler(new MinaClientHandle(json.toString()));
        //ConnectFuture dd=connector.connect(new InetSocketAddress("122.228.181.162", 9999));
        ConnectFuture dd = connector.connect(new InetSocketAddress(ip, port));
        try {
            Thread.sleep(2000);
            if(dd.getSession() != null){
                return dd;
            }else {
                dd = connector.connect(new InetSocketAddress(ip, port));
                Thread.sleep(2000);

            }
            if(dd.getSession() != null){
                return dd;
            }else {
                dd = connector.connect(new InetSocketAddress(ip, port));
                Thread.sleep(2000);

            }
            if(dd.getSession() != null){
                return dd;
            }else {
                dd = connector.connect(new InetSocketAddress(ip, port));
                Thread.sleep(2000);

            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return dd;
    }

    @Override
    public void createConnectPolicePay() {
        LambdaQueryWrapper<PolicePay> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PolicePay::getIsScan, 1);
        List<PolicePay> policePays = baseMapper.selectList(queryWrapper);
        for (int i = 0; i < policePays.size(); i++) {
            PolicePay policePay = policePays.get(i);
            getConnect(policePay.getIp(), Integer.parseInt(policePay.getPort()), policePay.getPayId(), policePay.getSecret());
        }
    }

    public ConnectFuture getConnectToSend(ConnectFuture dd,String payId ,String secret){
        // TODO Auto-generated method stub
        IoConnector connector = new NioSocketConnector();
        connector.setConnectTimeoutMillis(30000);
        TextLineCodecFactory lineCodec=new TextLineCodecFactory(Charset.forName("UTF-8"));
        lineCodec.setDecoderMaxLineLength(1024*1024*1024); //1G
        lineCodec.setEncoderMaxLineLength(1024*1024*1024); //1G
        connector.getFilterChain().addLast("codec",
                new ProtocolCodecFilter(lineCodec));
        //String payId="1001";
        //String secret="002f0c86af67473aa280c8d5ef165a19";
        JSONObject json=new JSONObject();
        json.put("method", "connectCheck");
        JSONObject data=new JSONObject();
        long time=System.currentTimeMillis();
        data.put("payId", payId);
        data.put("time", time);
        try {
            data.put("sign", MD5.md5(secret+time));
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }


        json=new JSONObject();
        json.put("method", "getUserInfo");
        data=new JSONObject();
        data.put("pageIndex", 1);
        data.put("pageSize", Enum.PolicePayNum.getName());
        json.put("data", data);
        dd.getSession().write(json.toString());
        return dd;
    }

    @Override
    public boolean getConnectAnd(String ip,int port,String payId,String secret,int pageIndex){
        // TODO Auto-generated method stub
        IoConnector connector = new NioSocketConnector();
        connector.setConnectTimeoutMillis(30000);
        TextLineCodecFactory lineCodec=new TextLineCodecFactory(Charset.forName("UTF-8"));
        lineCodec.setDecoderMaxLineLength(1024*1024*1024); //1G
        lineCodec.setEncoderMaxLineLength(1024*1024*1024); //1G
        connector.getFilterChain().addLast("codec",
                new ProtocolCodecFilter(lineCodec));
        //String payId="1001";
        //String secret="002f0c86af67473aa280c8d5ef165a19";
        JSONObject json=new JSONObject();
        json.put("method", "connectCheck");
        JSONObject data=new JSONObject();
        long time=System.currentTimeMillis();
        data.put("payId", payId);
        data.put("time", time);
        try {
            data.put("sign", MD5.md5(secret+time));
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        json.put("data", data);
        connector.setHandler(new MinaClientHandle(json.toString()));
        //ConnectFuture dd=connector.connect(new InetSocketAddress("122.228.181.162", 9999));
        ConnectFuture dd=connector.connect(new InetSocketAddress(ip, port));
        if(dd == null){
            return false;
        }
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        json=new JSONObject();
        json.put("method", "getUserInfo");
        data=new JSONObject();
        data.put("pageIndex", pageIndex);
        data.put("pageSize", Enum.PolicePayNum.getName());
        json.put("data", data);
        dd.getSession().write(json.toString());
        return true;
    }

    @Override
    public int insertPolicePay(PolicePay policePay) {
        LambdaQueryWrapper<PolicePay> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PolicePay::getInstitutionId, policePay.getInstitutionId());
        PolicePay policePay1 = baseMapper.selectOne(queryWrapper);
        if(policePay1 == null){
            baseMapper.insert(policePay);
            return 0;
        }else {
            policePay.setId(policePay1.getId());
            baseMapper.updateById(policePay);
            return policePay1.getIsScan();
        }

    }

    @Override
    public PolicePay selectByInstitutionId(String institutionId) {
        LambdaQueryWrapper<PolicePay> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PolicePay::getInstitutionId, institutionId);
        return baseMapper.selectOne(queryWrapper);
    }
}
